package com.szb.service;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.ListContainersCmd;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.api.model.Container;

import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.core.DefaultDockerClientConfig;

import com.szb.endpoint.WebSocketSessionManager;
import com.szb.entity.ContainerInfo;
import org.springframework.stereotype.Service;

import javax.websocket.Session;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

@Service(value = "dockerLogsService")
public class DockerLogsServiceImpl implements DockerLogsService{

    private final ExecutorService executor = Executors.newCachedThreadPool();
    private final BlockingQueue<String> messageQueue = new LinkedBlockingQueue<>();
    private final ConcurrentHashMap<String, Future<?>> loggingFutures = new ConcurrentHashMap<>();

    public void startLogging(String containerId, String sessionId) {

        if (loggingFutures.containsKey(containerId)) {
            System.out.println("日志任务已经在运行，不能重复启动。");
            return;
        }

        AtomicBoolean running = new AtomicBoolean(true);
        Session session = WebSocketSessionManager.getSession(sessionId);

        Thread senderThread = getThread(running, session);

        Future<?> future = executor.submit(() -> {
            // Docker日志读取逻辑
            ProcessBuilder pb = new ProcessBuilder("docker", "logs", "-f", containerId);
            Process process = null;
            try {
                process = pb.start();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                String line;
                while (running.get() && (line = reader.readLine()) != null) {
                    System.out.println(running.get()+line);
                    messageQueue.put(line); // 将消息放入队列以供发送线程处理
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
                // 处理异常
            } finally {
                running.set(false); // 停止发送线程
                try {
                    senderThread.join(); // 等待发送线程完成
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                // 清理资源（与原始代码相同）
            }
        });

        // 将Future存储到map中（假设loggingFutures已经定义）
        loggingFutures.put(containerId, future);
    }

    private Thread getThread(AtomicBoolean running, Session session) {
        Thread senderThread = new Thread(() -> {
            while (running.get() || !messageQueue.isEmpty()) {
                try {
                    String message = messageQueue.take();
                    synchronized (session) {
                        if (session.isOpen()) {
                            session.getBasicRemote().sendText(message);
                        } else {
                            running.set(false);
                        }
                    }
                } catch (IOException | InterruptedException e) {
                    running.set(false);
                    e.printStackTrace();
                }
            }
        });
        senderThread.start();
        return senderThread;
    }

    public void stopLogging(String containerId) {
        // 从map中获取对应的Future并取消它
        Future<?> future = loggingFutures.remove(containerId);
        if (future != null) {
            future.cancel(true); // 尝试取消任务
        } else {
            System.out.println("没有找到与容器ID关联的日志任务: " + containerId);
        }
    }

    public List<ContainerInfo> getRunningContainersInfo() {
        List<ContainerInfo> containerInfoList = new ArrayList<>();
        DockerClientConfig config;

        String dockerHost = System.getProperty("os.name").startsWith("Windows")
                ? "npipe:////./pipe/docker_engine"
                : "unix:///var/run/docker.sock";

        config = DefaultDockerClientConfig.createDefaultConfigBuilder()
                .withDockerHost(dockerHost)
                .build();

        try (DockerClient dockerClient = DockerClientBuilder.getInstance(config).build()) {
            ListContainersCmd listContainersCmd = dockerClient.listContainersCmd().withShowAll(true); // 仅显示运行中的容器
            List<Container> containers = listContainersCmd.exec();
            for (Container container : containers) {
                String id = container.getId();
                String[] names = container.getNames();
                List<String> namesList = Arrays.asList(names);
                String namesString = String.join(", ", namesList);
                containerInfoList.add(new ContainerInfo(id, namesString));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return containerInfoList;
    }
}
